package vboot.core.module.ass.oss.main;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import vboot.core.common.mvc.dao.JdbcDao;
import vboot.core.common.utils.file.XfileUtil;
import vboot.core.common.utils.web.XuserUtil;
import vboot.core.module.ass.oss.file.AssOssFile;
import vboot.core.module.ass.oss.file.AssOssFileRepo;
import vboot.core.module.ass.oss.root.AssOssLocalHand;
import vboot.core.module.ass.oss.root.AssOssRemoteHand;
import vboot.core.common.utils.lang.IdUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class AssOssMainService {

    public Zfile uploadFile(MultipartFile file) throws IOException, NoSuchAlgorithmException {
        String md5 = getMd5(file);
        AssOssFile dbFile = fileRepo.findByMd5(md5);
        Zfile zfile = new Zfile();
        if (dbFile != null) {//相同文件已上传过
            AssOssMain main = new AssOssMain();
            main.setId(IdUtils.getUID());
            main.setFilid(dbFile.getId());
            main.setName(file.getOriginalFilename());
            if (main.getName().contains(".")) {
                main.setType(main.getName().substring(main.getName().lastIndexOf(".") + 1));
            }
            repo.save(main);
            zfile.setId(main.getId());
            zfile.setName(main.getName());
            zfile.setSize(XfileUtil.getFileSize(dbFile.getZsize()));
            zfile.setPath(dbFile.getPath());
            zfile.setFilid(dbFile.getId());
        } else {
            AssOssFile newFile = localHand.upload(file,md5);
//            AssOssFile newFile = remoteHand.upload(file,md5);
            fileRepo.save(newFile);
            AssOssMain main = new AssOssMain();
            main.setId(newFile.getId());
            main.setFilid(newFile.getId());
            main.setName(file.getOriginalFilename());
            if (main.getName().contains(".")) {
                main.setType(main.getName().substring(main.getName().lastIndexOf(".") + 1));
            }
            main.setCrman(XuserUtil.getUser());
            repo.save(main);
            zfile.setId(main.getId());
            zfile.setName(main.getName());
            zfile.setSize(XfileUtil.getFileSize(newFile.getZsize()));
            zfile.setPath(newFile.getPath());
            zfile.setFilid(newFile.getId());
        }
        return zfile;
    }


    public void downloadFile(HttpServletRequest request, HttpServletResponse response,
                             String table, String id) throws Exception {
        String sql = "select t.path,t.name,f.service from " + table + " t " +
                "inner join ass_oss_file f on f.id=t.filid " +
                "where t.id=?";
        Map<String, Object> map = null;
        if (StrUtil.isNotBlank(table)) {
            map = jdbcDao.findMap(sql, id);
        }
        if (map == null) {
            sql = "select f.path,t.name,f.service from ass_oss_main t " +
                    "inner join ass_oss_file f on f.id=t.filid " +
                    "where t.id=?";
            map = jdbcDao.findMap(sql, id);
        }
        if("local".equals(map.get("service"))){
            localHand.download(request,response,(String) map.get("name"),(String) map.get("path"));
        }else{
            remoteHand.download(request, response, (String) map.get("name"), (String) map.get("path"));
        }
    }

    public int delete(String[] ids) {
        for (String id : ids) {
            repo.deleteById(id);
        }
        return ids.length;
    }

    public AssOssMain getInfo(String id){
        return repo.getOne(id);
    }

    public List<AssOssMain> getInfos(String ids){
        String[] arr= ids.split(",");
        List<String> list=Arrays.asList(arr);
        return repo.findAllById(list);
    }


    @Autowired
    private JdbcDao jdbcDao;

    @Autowired
    private AssOssLocalHand localHand;

    @Autowired
    private AssOssRemoteHand remoteHand;

    @Autowired
    private AssOssMainRepo repo;

    @Autowired
    private AssOssFileRepo fileRepo;

    private String getMd5(MultipartFile file) {
        try {
            //获取文件的byte信息
            byte[] uploadBytes = file.getBytes();
            // 拿到一个MD5转换器
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] digest = md5.digest(uploadBytes);
            //转换为16进制
            return new BigInteger(1, digest).toString(16);
//            MessageDigest messageDigest = MessageDigest.getInstance("md5");
//            return Base64.getEncoder().encodeToString(messageDigest.digest(file.getBytes()));
        } catch (IOException | NoSuchAlgorithmException e) {
            log.error("get file md5 error!!!", e);
        }
        return null;
    }

}
